package br.com.jvet.persistencia;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

@Stateless
public abstract class AbstractDAO<E, ID extends Serializable> implements
		GenericsDAO<E, ID> {

	@PersistenceContext
	private EntityManager entityManager;

	private Class<E> persistentClass;

	public AbstractDAO(Class<E> classe) {
		this.persistentClass = classe;
	}

	public Class<E> getPersistentClass() {
		return persistentClass;
	}

	public EntityManager getEntityManager() {
		return entityManager;
	}

	@Override
	public void incluir(E obj) {
		getEntityManager().persist(obj);
		getEntityManager().flush();
	}

	@Override
	public void alterar(E obj) {
		getEntityManager().merge(obj);
		getEntityManager().flush();
	}

	@Override
	public void excluir(ID id) {
		E entidadeRemover = consultarPorId(id);
		getEntityManager().remove(entidadeRemover);

	}

	@Override
	public E consultarPorId(ID id) {
		return getEntityManager().find(getPersistentClass(), id);
	}

	@Override
	public List<E> listar() {
		return buscarTodos();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<E> buscarTodos() {
		CriteriaQuery cq = getEntityManager().getCriteriaBuilder()
				.createQuery();
		cq.select(cq.from(getPersistentClass()));
		System.out.println("aqui listar>>" + cq.toString());
		return getEntityManager().createQuery(cq).getResultList();
	}

	@SuppressWarnings("unchecked")
	protected E buscarUmResultado(String namedQuery,
			Map<String, Object> parameters) {
		E result = null;

		try {
			Query query = getEntityManager().createQuery(namedQuery);
			System.out.println("busca por um result" + query);
			/**
			 * Method that will populate parameters if they are passed not null
			 * and empty
			 */
			if (parameters != null && !parameters.isEmpty()) {
				populateQueryParameters(query, parameters);
			}

			result = (E) query.getSingleResult();

		} catch (Exception e) {
			System.out.println("Error while running query: " + e.getMessage());
			e.printStackTrace();
		}

		return result;
	}

	@SuppressWarnings("unchecked")
	protected List<E> buscarListaParametro(String namedQuery,
			Map<String, Object> parameters) {
		List<E> results = null;

		try {
			Query query = getEntityManager().createQuery(namedQuery);

			if (parameters != null && !parameters.isEmpty()) {
				populateQueryParameters(query, parameters);
			}

			results = (List<E>) query.getResultList();

		} catch (Exception e) {
			System.out.println("Error while running query: " + e.getMessage());
			e.printStackTrace();
		}

		return results;
	}

	private void populateQueryParameters(Query query,
			Map<String, Object> parameters) {

		for (Entry<String, Object> entry : parameters.entrySet()) {
			query.setParameter(entry.getKey(), entry.getValue());
		}
	}

}
